# DefaultParameterBinders.java

    package org.codefilarete.stalactite.sql.statement.binder;

    import java.io.File;
    import java.io.InputStream;
    import java.math.BigDecimal;
    import java.nio.file.Path;
    import java.sql.Blob;
    import java.sql.Date;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.Timestamp;
    import java.time.LocalDate;
    import java.time.LocalDateTime;
    import java.time.LocalTime;
    import java.time.ZoneId;
    import java.util.UUID;

    import static org.codefilarete.stalactite.sql.statement.binder.DefaultPreparedStatementWriters.*;
    import static org.codefilarete.stalactite.sql.statement.binder.DefaultResultSetReaders.*;

    /**
     * Default {@link ParameterBinder}s mapped to methods of {@link ResultSet} and {@link PreparedStatement}
     *
     * @author Guillaume Mary
     */
    public final class DefaultParameterBinders {

    	/* Implementation note: although primitive binders are parameterized with generics they are not wrapped by a NullAwareParameterBinder
    	 * so they'll throw an exception or convert Object-typed value passed if null is writen or read.
    	 */

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getLong(String)} and {@link PreparedStatement#setLong(int, long)}.
    	 */
    	public static final ParameterBinder<Long> LONG_PRIMITIVE_BINDER = new LambdaParameterBinder<>(LONG_PRIMITIVE_READER, LONG_PRIMITIVE_WRITER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getLong(String)} and {@link PreparedStatement#setLong(int, long)}.
    	 * Wrapped into a {@link NullAwareParameterBinder} to manage type boxing and unboxing.
    	 */
    	public static final ParameterBinder<Long> LONG_BINDER = new NullAwareParameterBinder<>(LONG_PRIMITIVE_BINDER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getInt(String)} and {@link PreparedStatement#setInt(int, int)}.
    	 */
    	public static final ParameterBinder<Integer> INTEGER_PRIMITIVE_BINDER = new LambdaParameterBinder<>(INTEGER_PRIMITIVE_READER, INTEGER_PRIMITIVE_WRITER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getInt(String)} and {@link PreparedStatement#setInt(int, int)}.
    	 * Wrapped into a {@link NullAwareParameterBinder} to manage type boxing and unboxing.
    	 */
    	public static final ParameterBinder<Integer> INTEGER_BINDER = new NullAwareParameterBinder<>(INTEGER_PRIMITIVE_BINDER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getByte(String)} and {@link PreparedStatement#setByte(int, byte)}.
    	 */
    	public static final ParameterBinder<Byte> BYTE_PRIMITIVE_BINDER = new LambdaParameterBinder<>(BYTE_PRIMITIVE_READER, BYTE_PRIMITIVE_WRITER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getByte(String)} and {@link PreparedStatement#setByte(int, byte)}.
    	 * Wrapped into a {@link NullAwareParameterBinder} to manage type boxing and unboxing.
    	 */
    	public static final ParameterBinder<Byte> BYTE_BINDER = new NullAwareParameterBinder<>(BYTE_PRIMITIVE_BINDER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getBytes(String)} and {@link PreparedStatement#setBytes(int, byte[])}.
    	 */
    	public static final ParameterBinder<byte[]> BYTES_BINDER = new NullAwareParameterBinder<>(new LambdaParameterBinder<>(BYTES_READER, BYTES_WRITER));

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getDouble(String)} and {@link PreparedStatement#setDouble(int, double)}.
    	 */
    	public static final ParameterBinder<Double> DOUBLE_PRIMITIVE_BINDER = new LambdaParameterBinder<>(DOUBLE_PRIMITIVE_READER, DOUBLE_PRIMITIVE_WRITER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getDouble(String)} and {@link PreparedStatement#setDouble(int, double)}.
    	 * Wrapped into a {@link NullAwareParameterBinder} to manage type boxing and unboxing.
    	 */
    	public static final ParameterBinder<Double> DOUBLE_BINDER = new NullAwareParameterBinder<>(DOUBLE_PRIMITIVE_BINDER);

    	/**
    	 * {@link ParameterBinder} for {@link Number}. Bound to {@link PreparedStatement#setDouble(int, double)} and {@link PreparedStatement#setDouble(int, double)}.
    	 * Wrapped into a {@link NullAwareParameterBinder} to manage type boxing and unboxing.
    	 */
    	public static final ParameterBinder<Number> NUMBER_BINDER = new NullAwareParameterBinder<>(new LambdaParameterBinder<>(NUMBER_READER, NUMBER_WRITER));

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getFloat(String)} and {@link PreparedStatement#setFloat(int, float)}.
    	 * Wrapped into a {@link NullAwareParameterBinder} to manage type boxing and unboxing.
    	 */
    	public static final ParameterBinder<Float> FLOAT_PRIMITIVE_BINDER = new LambdaParameterBinder<>(FLOAT_PRIMITIVE_READER, FLOAT_PRIMITIVE_WRITER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getFloat(String)} and {@link PreparedStatement#setFloat(int, float)}.
    	 * Wrapped into a {@link NullAwareParameterBinder} to manage type boxing and unboxing.
    	 */
    	public static final ParameterBinder<Float> FLOAT_BINDER = new NullAwareParameterBinder<>(FLOAT_PRIMITIVE_BINDER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getBigDecimal(String)} and {@link PreparedStatement#setBigDecimal(int, BigDecimal)}.
    	 */
    	public static final ParameterBinder<BigDecimal> BIGDECIMAL_BINDER = new LambdaParameterBinder<>(BIGDECIMAL_READER, BIGDECIMAL_WRITER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getBoolean(String)} and {@link PreparedStatement#setBoolean(int, boolean)}.
    	 */
    	public static final ParameterBinder<Boolean> BOOLEAN_PRIMITIVE_BINDER = new LambdaParameterBinder<>(BOOLEAN_PRIMITIVE_READER, BOOLEAN_PRIMITIVE_WRITER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getBoolean(String)} and {@link PreparedStatement#setBoolean(int, boolean)}.
    	 * Wrapped into a {@link NullAwareParameterBinder} to manage type boxing and unboxing.
    	 */
    	public static final ParameterBinder<Boolean> BOOLEAN_BINDER = new NullAwareParameterBinder<>(BOOLEAN_PRIMITIVE_BINDER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getDate(String)} and {@link PreparedStatement#setDate(int, Date)}.
    	 * For common usage, prefer {@link DateBinder} because it uses {@link java.util.Date}
    	 * @see DateBinder
    	 */
    	public static final ParameterBinder<Date> DATE_SQL_BINDER = new LambdaParameterBinder<>(DATE_SQL_READER, DATE_SQL_WRITER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getTimestamp(String)} and {@link PreparedStatement#setTimestamp(int, Timestamp)}.
    	 */
    	public static final ParameterBinder<Timestamp> TIMESTAMP_BINDER = new LambdaParameterBinder<>(TIMESTAMP_READER, TIMESTAMP_WRITER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getString(String)} and {@link PreparedStatement#setString(int, String)}.
    	 */
    	public static final ParameterBinder<String> STRING_BINDER = new LambdaParameterBinder<>(STRING_READER, STRING_WRITER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getBinaryStream(String)} and {@link PreparedStatement#setBinaryStream(int, InputStream)}.
    	 * @see #BLOB_BINDER
    	 */
    	public static final ParameterBinder<InputStream> BINARYSTREAM_BINDER = new LambdaParameterBinder<>(BINARYSTREAM_READER, BINARYSTREAM_WRITER);

    	/**
    	 * {@link ParameterBinder} for {@link ResultSet#getBlob(String)} and {@link PreparedStatement#setBlob(int, Blob)}.
    	 *
    	 * @see #BINARYSTREAM_BINDER
    	 */
    	public static final ParameterBinder<Blob> BLOB_BINDER = new NullAwareParameterBinder<>(new LambdaParameterBinder<>(BLOB_READER, BLOB_WRITER));

    	/**
    	 * {@link ParameterBinder} for {@link java.util.Date}
    	 */
    	public static final ParameterBinder<java.util.Date> DATE_BINDER = new NullAwareParameterBinder<>(new DateBinder());

    	/**
    	 * {@link ParameterBinder} for {@link java.time.LocalDate}
    	 */
    	public static final ParameterBinder<LocalDate> LOCALDATE_BINDER = new NullAwareParameterBinder<>(new LocalDateBinder());

    	/**
    	 * {@link ParameterBinder} for {@link java.time.LocalDateTime}
    	 */
    	public static final ParameterBinder<LocalDateTime> LOCALDATETIME_BINDER = new NullAwareParameterBinder<>(new LocalDateTimeBinder());

    	/**
    	 * {@link ParameterBinder} for {@link java.time.LocalTime}
    	 */
    	public static final ParameterBinder<LocalTime> LOCALTIME_BINDER = new NullAwareParameterBinder<>(new LocalTimeBinder());

    	/**
    	 * {@link ParameterBinder} for {@link java.time.ZoneId}.
    	 * It may have little purpose alone, but has its interest with {@link java.time.ZonedDateTime}.
    	 */
    	public static final ParameterBinder<ZoneId> ZONEID_BINDER = new NullAwareParameterBinder<>(new ZoneIdBinder());

    	/**
    	 * {@link ParameterBinder} for {@link UUID}.
    	 */
    	public static final ParameterBinder<UUID> UUID_BINDER = new NullAwareParameterBinder<>(new UUIDParameterBinder());

    	/**
    	 * {@link ParameterBinder} for {@link Path}.
    	 */
    	public static final ParameterBinder<Path> PATH_BINDER = new NullAwareParameterBinder<>(new PathBinder());

    	/**
    	 * {@link ParameterBinder} for {@link File}.
    	 */
    	public static final ParameterBinder<File> FILE_BINDER = new NullAwareParameterBinder<>(new FileBinder());

    	private DefaultParameterBinders() {
    		// Class for constants
    	}
    }